
SendARP 	Proto :DWord, :DWord, :DWord, :DWord
malloc 		Proto C :DWord
strcpy 		Proto C :Ptr SByte, :Ptr SByte

.Const

.Data?

g_cs		CRITICAL_SECTION <?>
g_lan_list	DD 	?

.Data

sz_format_ip			DB  "%d.%d.%d.%d", 0
sz_format_ip_stye		DB  "%d.%d.%d.%%d", 0
sz_ip_format			DB  "%s", 0AH, 0DH, 0
sz_ip_format2			DB  "my%s", 0AH, 0DH, 0
sz_ip_format3			DB  "you%s", 0AH, 0DH, 0
sz_create_thread_err    DB  "create thread %d error! code %d", 0AH, 0DH, 0
sz_msg					DB  "g_lan_lis is NULL!", 0AH, 0DH, 0

.Code

;
; get list of lan host
;

get_lan_list Proc Uses Edi Esi Ebx

	Local sz_format[18]:Byte
	Local sz_ip_temp[18]:Byte
	Local h_thread[254]:DWord
	Local i:DWord

	Lea Eax, [g_cs]
	Push Eax
	Call InitializeCriticalSection

	;
	; we format the ip address to XXX.XXX.XXX.%d
	;

	Lea Eax, [sz_format]
	Push Eax
	Lea Eax, [g_sz_gateway_ip]
	Push Eax
	Call format_ip_string

	;
	; print the result
	;

;	Lea Eax, [sz_format]
;	Push Eax
;	Call printf
;	Add Esp, 4

;	    For(register i = 0 ; i < 10; i++ )
;	    {
;	        sprintf( sz_ip, sz_format, i+1 );
;	        printf( "%s\n", sz_test1 );
;	    }

	Mov i, 0
	Jmp @for_1
@add_1:

	Add i, 1

@for_1:

	Cmp i, 0FEH
	Jge @finish

	;
	; call sprintf
	;

	Push 18
	Call malloc
	Add Esp, 4
	Mov Ebx, Eax

	Mov Ecx, i
	Add Ecx, 1
	Push Ecx
	Lea Eax, [sz_format]
	Push Eax
	;Lea Eax, [sz_ip_temp]
	Push Ebx
	Call sprintf
	Add Esp, 12

	;
	; print the ip address
	;

;	Lea Ecx, [sz_ip_temp]
;	Push Ebx
;	Lea Eax, [sz_ip_format]
;	Push Eax
;	Call printf
;	Add Esp, 8

	;
	; here we create the thread which can help us get the mac of specific ip address
	;


	Push 0
	Push 0
	;Lea Ecx, [sz_ip_temp]
	Push Ebx
	Lea Eax, [thread_get_host]
	Push Eax
	Push 0
	Push 0
	Call CreateThread


	Test Eax, Eax
	Jz @add_1

	Push 2
	Call Sleep

	;
	; save the handle of the thread
	;

	Mov Ecx, i
	Mov DWord Ptr [h_thread + Ecx * 4], Eax

	Jmp @add_1

@finish:

	;
	; wait for thread end
	;

	Lea Eax, [h_thread]
	Push INFINITE
	Push 1
	Push Eax
	Push MAXIMUM_WAIT_OBJECTS
	Call WaitForMultipleObjects

	Lea Eax, DWord Ptr [h_thread + 64 * 4]
	Push INFINITE
	Push 1
	Push Eax
	Push MAXIMUM_WAIT_OBJECTS
	Call WaitForMultipleObjects

	Lea Eax, DWord Ptr [h_thread + 128 * 4]
	Push INFINITE
	Push 1
	Push Eax
	Push MAXIMUM_WAIT_OBJECTS
	Call WaitForMultipleObjects

	Lea Eax, DWord Ptr [h_thread + 192 * 4]
	Push INFINITE
	Push 1
	Push Eax
	Push 62
	Call WaitForMultipleObjects

	Lea Eax, [g_cs]
	Push Eax
	Call DeleteCriticalSection

	Ret

get_lan_list EndP

; /** \fn format_ip_string Proc sz_in:Ptr SByte, sz_out:Ptr SByte
;	  \brief format the ip address to XXX.XXX.XXX.%d
; */

format_ip_string Proc Uses Edi Esi Ebx, sz_in:Ptr SByte, sz_out:Ptr SByte
	
	Local ip1:DWord, ip2:DWord, ip3:DWord, ip4:DWord

    Lea Eax, [ip4]
    Push Eax
    Lea Eax, [ip3]
    Push Eax
    Lea Eax, [ip2]
    Push Eax
    Lea Eax, [ip1]
    Push Eax
	Lea Ebx, [sz_format_ip]
	Push Ebx
	Mov Eax, [sz_in]
	Push Eax
	Call sscanf
	Add Esp, 24

	;
	; fill string with 0
	;

	Mov Ecx, 18
	Xor Eax, Eax
	Mov Edi, [sz_out]
	Rep Stos Byte Ptr [Edi]

	Push ip3
	Push ip2
	Push ip1
	Lea Ebx, [sz_format_ip_stye]
	Push Ebx
	Mov Eax, [sz_out]
	Push Eax
	Call sprintf
	Add Esp, 20

	Ret
format_ip_string EndP

; /** \fn bool get_mac_from_ip( IN char* sz_ip, OUT BYTE* bt_mac )
;
;	  \brief the same as it's name
; */

get_mac_from_ip Proc Uses Edi Esi Ebx, sz_ip:Ptr SByte, bt_mac:Ptr SByte

	Local u_mac[2]:DWord
	Local u_size:DWord

	Mov DWord Ptr [u_size], 6

	Lea Edx, [u_size]
	Push Edx
	Lea Ecx, [u_mac]
	Push Ecx
	Push 0
	Mov Eax, [sz_ip]
	Push Eax
	Call inet_addr
	Push Eax
	Call SendARP

	Test Eax, Eax
	Jnz @err

	;
	; here we get the mac of specific ip address
	;

	Xor Ecx, Ecx
	Mov Ecx, 6
	Lea Esi, [u_mac]
	Mov Edi, [bt_mac]
	Rep Movsb

	Xor Eax, Eax
	Mov Ax, 1
	Ret

@err:

	Xor Eax, Eax
	Mov Ax, 0
	Ret

get_mac_from_ip EndP

; /** \fn thread_get_host Proc lparam:DWord
;  *	\brief the thread for getting mac from ip ,at the same time put the data to link table
;  */

thread_get_host Proc Uses Edi Esi Ebx, _lparam

	Local bt_mac[6]:Byte
	Local p_ip_list:PIP_LIST

	Lea Ecx, [bt_mac]
	Push Ecx
	Mov Eax, [_lparam]
	Push Eax
	Call get_mac_from_ip

	Test Eax, Eax
	Jz @end

	;
	; here we have gotten the mac,so the next work is save the mac we have gotten
	;
	
	Lea Eax, [g_cs]
	Push Eax
	Call EnterCriticalSection
	
	;
	; save data
	;

	Mov Eax, SizeOf IP_LIST
	Push Eax
	Call malloc
	Add Esp, 4

	Mov Ebx, Eax

	Mov Ecx, SizeOf IP_LIST
	Xor Eax, Eax
	Mov Edi, Ebx
	Rep Stos Byte Ptr [Edi]

	Assume Ebx:Ptr IP_LIST

	;
	; we want to copy string first we should get the length of string
	;

	Xor Eax, Eax
	Or Ecx, -1
	Mov Edi, [_lparam]
	Repne Scas Byte Ptr [Edi]
	Not Ecx

	;
	; copy string
	;

	Mov Esi, [_lparam]
	Lea Edi, [Ebx].sz_ip
	Rep Movsb


	Lea Esi, [bt_mac]
	Lea Edi, [Ebx].sz_mac
	Xor Ecx, Ecx
	Mov Cx, 6
	Rep Movsb

	Push Ebx
	Call add_to_list

	Assume Ebx:Nothing
	
	Lea Eax, [g_cs]
	Push Eax
	Call LeaveCriticalSection
	
	;
	; delete the memery we allocate
	;

	Mov Eax, [_lparam]
	Push Eax
	Call free
	Add Esp, 4
@end:
	Ret

thread_get_host EndP


add_to_list Proc Private Uses Edi Esi Ebx, p_add:PIP_LIST

	Local p_temp:PIP_LIST
	
	;
	; first we check up the g_list_lan is NULL or not
	;

	Cmp DWord Ptr [g_lan_list], 0
	Jnz @while_start
	Mov Eax, [p_add]
	Mov DWord Ptr [g_lan_list], Eax
	Jmp @end

@while_start:

	Mov Ecx, DWord Ptr [g_lan_list]
	Mov DWord Ptr [p_temp], Ecx
@while:
	Mov Ebx, DWord Ptr [p_temp]
	Assume Ebx:Ptr IP_LIST
	Cmp [Ebx].next, 0
	Jz @add
	Mov Eax, [Ebx].next
	Mov DWord Ptr [p_temp], Eax
	Assume Ebx:Nothing
	Jmp @while

@add:
	Mov Ebx, DWord Ptr [p_temp]
	Assume Ebx:Ptr IP_LIST
	Mov Eax, DWord Ptr [p_add]
	Mov [Ebx].next, Eax
	Assume Ebx:Nothing
@end:
	
	Ret

add_to_list EndP

print_list Proc

	Local p_temp:PIP_LIST

	Cmp DWord Ptr [g_lan_list], 0
	Jz @end
	Mov Eax, DWord Ptr [g_lan_list]
	Mov DWord Ptr [p_temp], Eax
@while:
	Mov Ebx, DWord Ptr [p_temp]
	Assume Ebx:Ptr IP_LIST

	Lea Ecx, [Ebx].sz_ip
	Push Ecx
	Lea Eax, [sz_ip_format]
	Push Eax
	Call printf
	Add Esp, 8
	
	Cmp [Ebx].next, 0
	Jz @ret
	Mov Eax, [Ebx].next
	Mov DWord Ptr [p_temp], Eax
	Assume Ebx:Nothing
	Jmp @while

@end:
	Lea Eax, [sz_msg]
	Push Eax
	Call printf
	Add Esp, 4
@ret:
	Ret
print_list EndP

find_in_link proc uses edi esi ebx, n_ip:dword
	
	Local ip1:DWord, ip2:DWord, ip3:DWord, ip4:DWord
	Local p_temp:PIP_LIST
	
	cmp dword ptr[g_lan_list], 0
	jz @no_find_end
	
	mov eax, dword ptr[g_lan_list]
	mov dword ptr[p_temp], eax
@while:
	
	mov ebx, dword ptr [p_temp]
	
	assume ebx:ptr IP_LIST
	
	;
	; split ip address
	;
	
	lea eax, [ip4]
    push eax
    lea ecx, [ip3]
    push Ecx
    lea eax, [ip2]
    push eax
    lea ecx, [ip1]
    push ecx
	lea ecx, [sz_format_ip]
	push ecx
	lea eax, [ebx].sz_ip
	push eax
	call sscanf
	add esp, 24
	
	;
	; check out
	;
	
	mov eax, n_ip
	cmp ip4, eax
	jz @find
	
	;
	; next
	;
	
	cmp [ebx].next, 0
	Jz @no_find_end
	
	mov eax, [ebx].next
	mov dword ptr [p_temp], eax
		
	assume ebx: nothing
	
	jmp @while

@find:

	xor eax, eax
	mov eax, ebx
	ret
	
@no_find_end:

	xor eax, eax
	ret
	
find_in_link endp





















